package entity

import (
	"database/sql"
	"strings"

	"gitee.com/linxing_3/sr-core/yal/ystr"
)

type DBTables struct {
	Schema         string       `gorm:"column:TABLE_SCHEMA" json:"schema"`
	TableName      string       `gorm:"column:TABLE_NAME" json:"tableName"`
	Engine         string       `gorm:"column:ENGINE" json:"engine"`
	TableRows      string       `gorm:"column:TABLE_ROWS" json:"tableRows"`
	TableCollation string       `gorm:"column:TABLE_COLLATION" json:"tableCollation"`
	CreateTime     string       `gorm:"column:CREATE_TIME" json:"createTime"`
	UpdateTime     string       `gorm:"column:UPDATE_TIME" json:"updateTime"`
	TableComment   string       `gorm:"column:TABLE_COMMENT" json:"tableComment"`
	Columns        []*DBColumns `gorm:"-" json:"columns"`
}

type DBColumns struct {
	TableSchema            string `gorm:"column:TABLE_SCHEMA" json:"tableSchema"`
	TableName              string `gorm:"column:TABLE_NAME" json:"tableName"`
	ColumnName             string `gorm:"column:COLUMN_NAME" json:"columnName"`
	ColumnDefault          string `gorm:"column:COLUMN_DEFAULT" json:"columnDefault"`
	IsNullable             string `gorm:"column:IS_NULLABLE" json:"isNullable"`
	DataType               string `gorm:"column:DATA_TYPE" json:"dataType"`
	CharacterMaximumLength string `gorm:"column:CHARACTER_MAXIMUM_LENGTH" json:"characterMaximumLength"`
	CharacterSetName       string `gorm:"column:CHARACTER_SET_NAME" json:"characterSetName"`
	ColumnType             string `gorm:"column:COLUMN_TYPE" json:"columnType"`
	ColumnKey              string `gorm:"column:COLUMN_KEY" json:"columnKey"`
	Extra                  string `gorm:"column:EXTRA" json:"extra"`
	ColumnComment          string `gorm:"column:COLUMN_COMMENT" json:"columnComment"`
}

type DBColumnsSqlite struct {
	Name      string         // 列名
	Type      string         // 数据类型
	NotNull   int            // 是否允许NULL（0允许，1不允许）
	DfltValue sql.NullString // 默认值（可能为NULL）
	Pk        int            // 是否为主键（0否，1是）
}

func (d DBColumns) IsPK() bool { return strings.ToLower(d.ColumnKey) == "pri" }
func (d DBColumns) IsPkInt() int {
	if d.IsPK() {
		return 1
	}
	return -1
}

func (t *DBTables) ToModuleTable() *ModuleTable {
	res := &ModuleTable{
		Domain:      t.Schema,
		ClassName:   ystr.CamelString(t.TableName),
		DBTable:     t.TableName,
		Comment:     t.TableComment,
		DomainRoute: ystr.CaptainLower(t.Schema),
		ClassRoute:  ystr.CaptainLower(ystr.CamelString(t.TableName)),
		Auth:        1,
	}
	for _, col := range t.Columns {
		res.Fields = append(res.Fields, col.ToModuleCol())
	}

	return res
}

func boolToInt(b bool) int {
	if b {
		return 1
	}
	return -1
}

func (c *DBColumns) ToModuleCol() *ModuleField {
	camCol := ystr.CamelString(c.ColumnName)
	cType := strings.ToLower(c.ColumnType)
	return &ModuleField{
		Domain:    c.TableSchema,
		ClassName: c.TableName,
		FieldName: camCol,
		IsPk:      boolToInt(c.IsPK()),
		IsIndex:   boolToInt(c.ColumnKey != ""),
		IsUnique:  boolToInt(strings.Contains(c.ColumnKey, "UNI")),
		NullAble:  boolToInt(c.IsNullable == "YES" || c.IsNullable == "1"),
		JsonName:  ystr.CaptainLower(camCol),
		GoType:    ParseColumnTypeToGoType(cType),
		TsType:    ParseColumnTypeToTsType(cType),
		Comment:   c.ColumnComment,
		InSearch:  1,
		InCreate:  1,
		InEdit:    1,
	}
}
